/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package com.gzx.bi.modular.goals.advance.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gzx.bi.modular.goals.advance.entity.AdvancePayments;
import com.gzx.bi.modular.goals.advance.entity.vo.AdvancePaymentsExcelImport;
import com.gzx.bi.modular.goals.advance.entity.vo.AdvancePaymentsVo;
import com.gzx.bi.modular.goals.advance.mapper.AdvancePaymentsMapper;
import com.gzx.bi.modular.goals.advance.param.AdvancePaymentsAddParam;
import com.gzx.bi.modular.goals.advance.param.AdvancePaymentsEditParam;
import com.gzx.bi.modular.goals.advance.param.AdvancePaymentsIdParam;
import com.gzx.bi.modular.goals.advance.param.AdvancePaymentsPageParam;
import com.gzx.bi.modular.goals.advance.service.AdvancePaymentsService;
import com.gzx.bi.modular.goals.monthly.entity.GzxMonthlyGoals;
import com.gzx.bi.modular.goals.monthly.entity.vo.GzxMonthlyGoalsVo;
import com.gzx.bi.modular.goals.monthly.mapper.GzxMonthlyGoalsMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.common.util.CommonDateUtil;
import vip.xiaonuo.common.util.CommonExcelUtil;
import vip.xiaonuo.common.util.MapstructUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 垫付金额Service接口实现类
 *
 * @author 刘志刚
 * @date 2025/01/15 17:01
 **/
@Service
@RequiredArgsConstructor
public class AdvancePaymentsServiceImpl extends ServiceImpl<AdvancePaymentsMapper, AdvancePayments> implements AdvancePaymentsService {

    private final AdvancePaymentsMapper advancePaymentsMapper;

    private final GzxMonthlyGoalsMapper monthlyGoalsMapper;

    @Override
    @DS("bi")
    public Page<AdvancePaymentsVo> page(AdvancePaymentsPageParam advancePaymentsPageParam) {
        LambdaQueryWrapper<AdvancePayments> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdvancePayments::getGzxMonthlyGoalsId, advancePaymentsPageParam.getId());
        Page<AdvancePayments> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        Page<AdvancePaymentsVo> advancePaymentsVoPage = new Page<>();
        advancePaymentsVoPage.setRecords(MapstructUtils.convert(page.getRecords(), AdvancePaymentsVo.class));
        advancePaymentsVoPage.setTotal(page.getTotal());
        advancePaymentsVoPage.setCurrent(page.getCurrent());
        return advancePaymentsVoPage;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @DS("bi")
    public void add(AdvancePaymentsAddParam advancePaymentsAddParam) {
        AdvancePayments advancePayments = BeanUtil.toBean(advancePaymentsAddParam, AdvancePayments.class);
        GzxMonthlyGoalsVo monthlyGoalsVo = monthlyGoalsMapper.selectVoById(advancePaymentsAddParam.getGzxMonthlyGoalsId());
        advancePayments.setCompany(monthlyGoalsVo.getDeptId());
        advancePayments.setProject(monthlyGoalsVo.getProjectCode());
        advancePayments.setBatch(monthlyGoalsVo.getBatchNumber());
        monthlyGoalsMapper.updateAdvancePaymentAmount(advancePayments.getGzxMonthlyGoalsId(), monthlyGoalsVo.getAdvancePayment().add(advancePayments.getAdvancedPaymentAmount()));
        this.save(advancePayments);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @DS("bi")
    public void edit(AdvancePaymentsEditParam advancePaymentsEditParam) {
        //新的
        BigDecimal newMoney = advancePaymentsEditParam.getAdvancedPaymentAmount();
        AdvancePayments advancePayments = this.queryEntity(advancePaymentsEditParam.getId().toString());
        GzxMonthlyGoals gzxMonthlyGoals = monthlyGoalsMapper.selectById(advancePayments.getGzxMonthlyGoalsId());
        BigDecimal oldMoney = advancePayments.getAdvancedPaymentAmount();
        BeanUtil.copyProperties(advancePaymentsEditParam, advancePayments);
        advancePayments.setGzxMonthlyGoalsId(null);
        BigDecimal newValue = gzxMonthlyGoals.getAdvancePayment().subtract(oldMoney).add(newMoney);
        monthlyGoalsMapper.updateAdvancePaymentAmount(gzxMonthlyGoals.getId(), newValue);
        this.updateById(advancePayments);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @DS("bi")
    public void delete(List<AdvancePaymentsIdParam> advancePaymentsIdParamList) {
        BigDecimal money = BigDecimal.ZERO;
        ArrayList<Long> ids = new ArrayList<>();
        for (AdvancePaymentsIdParam advancePaymentsIdParam : advancePaymentsIdParamList) {
            ids.add(advancePaymentsIdParam.getId());
        }
        List<AdvancePayments> advancePayments = advancePaymentsMapper.selectBatchIds(ids);
        for (AdvancePayments selectBatchId : advancePayments) {
            money = money.add(selectBatchId.getAdvancedPaymentAmount());
        }
        if (advancePayments.size() > 0) {
            Long parentId = advancePayments.get(0).getGzxMonthlyGoalsId();
            GzxMonthlyGoals gzxMonthlyGoals = monthlyGoalsMapper.selectById(parentId);
            gzxMonthlyGoals.setAdvancePayment(gzxMonthlyGoals.getAdvancePayment().subtract(money));
            monthlyGoalsMapper.updateAdvancePaymentAmount(parentId, gzxMonthlyGoals.getAdvancePayment());
        }
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(advancePaymentsIdParamList, AdvancePaymentsIdParam::getId));
    }

    @Override
    @DS("bi")
    public AdvancePayments detail(AdvancePaymentsIdParam advancePaymentsIdParam) {
        return this.queryEntity(advancePaymentsIdParam.getId().toString());
    }

    @Override
    @DS("bi")
    public AdvancePayments queryEntity(String id) {
        AdvancePayments advancePayments = this.getById(id);
        if (ObjectUtil.isEmpty(advancePayments)) {
            throw new CommonException("垫付金额不存在，id值为：{}", id);
        }
        return advancePayments;
    }

    /**
     * 批量导入垫付金额
     *
     * @param file
     * @param val
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importExcel(MultipartFile file, String val) {
        List<AdvancePaymentsExcelImport> excelResultList = null;
        try {
            excelResultList = CommonExcelUtil.importExcel(file, AdvancePaymentsExcelImport.class);
        } catch (Exception e) {
            throw new CommonException("Excel导入失败");
        }
        if (CollectionUtil.isEmpty(excelResultList)) {
            throw new CommonException("Excel为空");
        }
        GzxMonthlyGoalsVo gzxMonthlyGoalsVo = monthlyGoalsMapper.selectVoById(val);
        String deptId = gzxMonthlyGoalsVo.getDeptId();
        String projectCode = gzxMonthlyGoalsVo.getProjectCode();
        String batchNumber = gzxMonthlyGoalsVo.getBatchNumber();
        List<AdvancePayments> list = MapstructUtils.convert(excelResultList, AdvancePayments.class);
        BigDecimal totalMoney = BigDecimal.ZERO;
        int num = 0;
        for (AdvancePayments advancePayments : list) {
            if (advancePayments.getRegistrationDate() == null
                    || advancePayments.getDebtorName() == null
                    || advancePayments.getUnpaidAmount() == null
                    || advancePayments.getNeedRepaymentAmount() == null
                    || advancePayments.getAdvancedPaymentAmount() == null
                    || advancePayments.getOperatingEmployee() == null
                    || advancePayments.getTotalCommissionEstimate() == null
                    || advancePayments.getAccountAge() == null
                    || advancePayments.getAdvancePaymentRatio() == null
                    || advancePayments.getCommissionRatio() == null) {
                num++;
                throw new CommonException("第" + num + "行数据有数据为空");
            }
            if (advancePayments.getAdvancedPaymentAmount().compareTo(BigDecimal.ZERO) >= 0) {
                totalMoney = totalMoney.add(advancePayments.getAdvancedPaymentAmount());
            } else {
                throw new CommonException(num + "垫付金额不能为空");
            }
            advancePayments.setProject(projectCode);
            advancePayments.setCompany(deptId);
            advancePayments.setBatch(batchNumber);
            advancePayments.setGzxMonthlyGoalsId(Long.parseLong(val));
        }
        AdvancePayments advancePayments = list.get(0);
        Long gzxMonthlyGoalsId = advancePayments.getGzxMonthlyGoalsId();
        GzxMonthlyGoals gzxMonthlyGoals = monthlyGoalsMapper.selectById(gzxMonthlyGoalsId);
        BigDecimal result = gzxMonthlyGoals.getAdvancePayment().add(totalMoney);
        monthlyGoalsMapper.updateAdvancePaymentAmount(gzxMonthlyGoalsId, result);
        this.saveBatch(list);
    }

    /**
     * 获取上月1号截止到上月今天的垫付金额
     *
     * @return
     */
    @DS("bi")
    @Override
    public List<AdvancePayments> getLastMonthAdvancePayments() {
        List<GzxMonthlyGoals> lastMonthGoalsList = monthlyGoalsMapper.selectList(Wrappers.<GzxMonthlyGoals>lambdaQuery()
                .eq(GzxMonthlyGoals::getBelongingMonth, CommonDateUtil.getLastMonth()));
        List<Long> lastMonthGoalsIdList = lastMonthGoalsList.stream().map(GzxMonthlyGoals::getId).toList();
        return advancePaymentsMapper.selectList(Wrappers.<AdvancePayments>lambdaQuery()
                .in(AdvancePayments::getGzxMonthlyGoalsId, lastMonthGoalsIdList));
    }

    /**
     * 获昨天的垫付金额
     *
     * @return
     */
    @Override
    public List<AdvancePayments> getYesterdayAdvancePayments() {
        return advancePaymentsMapper.selectList(Wrappers.<AdvancePayments>lambdaQuery()
                .eq(AdvancePayments::getRegistrationDate, CommonDateUtil.getOffsetDateStr(-1)));
    }


}
